import {Context, Next} from 'koa';
import {RouterCtrl} from "../RouterCtrl";
import _ from 'lodash';
import {ResponseBeautifier, ResponseInfo} from "../../utils/ResponseBeautifier";
import {ModelUtil} from "../../db/ModelUtil";

export class SystemCtrl {

    public static async addProject(ctx: Context, next: Next) {
        const parame: any = ctx.request.body;
        const checkResult = RouterCtrl.checkProject(parame.path);
        if (checkResult.code !== 200) {
            return ResponseBeautifier.response(ctx, checkResult);
        }
        const count = await ModelUtil.project.countDocuments({path: parame.path});
        if (count >= 1) {
            return ResponseBeautifier.responseByStatus(ctx, ResponseInfo.dataError, "该存在项目路径相同的结果!");
        }
        const entity = new ModelUtil.project(parame);
        await entity.save();
        ResponseBeautifier.success(ctx);
    }

    public static async deleteProject(ctx: Context, next: Next) {
        const parame: any = ctx.request.query;
        const res = await ModelUtil.project.deleteOne({id: parame.id});
        if (res.deletedCount === 0) {
            return ResponseBeautifier.responseByStatus(ctx, ResponseInfo.dataError, "项目删除失败!");
        }
        await ModelUtil.router.deleteMany({projectId: parame.id});
        ResponseBeautifier.success(ctx, res);
    }

    public static async updateProject(ctx: Context, next: Next) {
        const parame: any = ctx.request.body;
        const checkResult = RouterCtrl.checkProject(parame.path);
        if (checkResult.code !== 200) {
            return ResponseBeautifier.response(ctx, checkResult);
        }
        const oldProject = await ModelUtil.project.findOne({id: parame.id}, {path: 1});
        if (_.isNull(oldProject)) {
            return ResponseBeautifier.responseByStatus(ctx, ResponseInfo.dataError, "不存在改项目!");
        }
        const res = await ModelUtil.project.updateOneByReadOnly({id: parame.id}, parame);
        if (res.matchedCount === 0) {
            return ResponseBeautifier.responseByStatus(ctx, ResponseInfo.dataError, "项目更新失败!");
        }
        const newProject = await ModelUtil.project.findOne({id: parame.id});
        if (newProject.disable) {
            const routers = await ModelUtil.router.find({projectId: oldProject.id});
            if (routers.length >= 0) {
                RouterCtrl.removeByStartsWith(oldProject.path);
                RouterCtrl.addByRouters(parame.path, routers);
            }
        }
        ResponseBeautifier.success(ctx);
    }

    public static async getAllProject(ctx: Context, next: Next) {
        const {page = 0, limit = 10} = ctx.request.query;
        const res = await ModelUtil.project.findByPage({}, {id: 1, name: 1, path: 1, _id: 0}, page, limit)
        ResponseBeautifier.success(ctx, res);
    }

    public static async addRouter(ctx: Context, next: Next) {
        const parame: any = ctx.request.body;
        parame.method = parame.method || "get";
        const checkResult = RouterCtrl.checkRouter(parame);
        if (checkResult.code !== 200) {
            return ResponseBeautifier.response(ctx, checkResult);
        }
        const res1 = await ModelUtil.router.countDocuments({projectId: parame.projectId, path: parame.path});
        if (res1 > 0) {
            return ResponseBeautifier.responseByStatus(ctx, ResponseInfo.dataError, "已存在该路由了!");
        }
        const project = await ModelUtil.project.findOne({id: parame.projectId});
        if (_.isNull(project)) {
            return ResponseBeautifier.responseByStatus(ctx, ResponseInfo.dataError, "不存在改项目!");
        }
        const adRes = await RouterCtrl.addRouter(project.path, parame);
        if (adRes.code !== 200) {
            return ResponseBeautifier.response(ctx, adRes);
        }
        const entity = new ModelUtil.router(parame);
        await entity.save();
        ResponseBeautifier.success(ctx);
    }

    public static async removeRouter(ctx: Context, next: Next) {
        const parame: any = ctx.request.query;
        const routerInfo = await ModelUtil.router.findOne({id: parame.id});
        if (_.isNull(routerInfo)) {
            return ResponseBeautifier.responseByStatus(ctx, ResponseInfo.dataError, "不存在该路由!");
        }
        const deleteInfo = await ModelUtil.router.deleteOne({id: parame.id});
        if (deleteInfo.deletedCount !== 1) {
            return ResponseBeautifier.responseByStatus(ctx, ResponseInfo.dataError, "路由删除失败!");
        }
        if (routerInfo.disable) {
            return ResponseBeautifier.success(ctx);
        }
        const project = await ModelUtil.project.findOne({id: routerInfo.projectId});
        if (_.isNull(project)) {
            return ResponseBeautifier.responseByStatus(ctx, ResponseInfo.dataError, "不存在该项目!");
        }
        ctx.body = RouterCtrl.removeRouter(project.path, routerInfo.path);
    }

    public static async updateRouter(ctx: Context, next: Next) {
        const parame: any = ctx.request.body;
        const checkResult = RouterCtrl.checkRouter(parame);
        if (checkResult.code !== 200) {
            return ResponseBeautifier.response(ctx, checkResult);
        }
        const oldRouterInfo = await ModelUtil.router.findOne({id: parame.id});
        if (!oldRouterInfo) {
            return ResponseBeautifier.responseByStatus(ctx, ResponseInfo.dataError, "找不到该路由!");
        }
        const project = await ModelUtil.project.findOne({id: oldRouterInfo.projectId});
        if (_.isNull(project)) {
            return ResponseBeautifier.responseByStatus(ctx, ResponseInfo.dataError, "不存在该项目!");
        }
        const res = await ModelUtil.router.updateOneByReadOnly({id: parame.id}, parame);
        if (res.matchedCount !== 1) {
            return ResponseBeautifier.responseByStatus(ctx, ResponseInfo.dataError, "更新失败!");
        }
        ctx.body = await RouterCtrl.updateRouter(project.path, oldRouterInfo.path, parame);
    }

    public static async getAllRouter(ctx: Context, next: Next) {
        const {page = 0, limit = 10} = ctx.request.query;
        const res = await ModelUtil.router.findByPage({}, {
            id: 1,
            projectId: 1,
            path: 1,
            description: 1,
            method: 1,
            disable: 1,
            _id: 0
        }, page, limit)
        ResponseBeautifier.success(ctx, res);
    }

    public static async getAllRouterByProject(ctx: Context, next: Next) {
        const {id, page = 0, limit = 10} = ctx.request.query;
        const res = await ModelUtil.router.findByPage({projectId: id}, {
            id: 1, projectId: 1, description: 1, path: 1, method: 1, _id: 0, disable: 1, handler: 1
        }, page, limit)
        ResponseBeautifier.success(ctx, res);
    }
}
